# coding:utf-8
'''
	辅助工具类
	汉中库得网络科技
	电子信箱：yyc1030@qq.com
'''
import os
import importlib
from PySide2 import QtCore
from PySide2 import QtGui
from PySide2 import QtWidgets
from pymxs import runtime as rt
import pymxs
import tools

import CopyModelAction, PasteModelAction, BuildModel, render, About
importlib.reload(CopyModelAction)
importlib.reload(PasteModelAction)
importlib.reload(BuildModel)
importlib.reload(render)
importlib.reload(About)

# 工具栏
class ToolBar(QtWidgets.QToolBar):
	# rootPath 插件运行环境根目录
	# parent 3DMax的主窗体
	def __init__(self, app):
		super(ToolBar, self).__init__(app.mainWindow)
		
		self.toolbarArea = {
			"1": QtCore.Qt.LeftToolBarArea,
			"2": QtCore.Qt.RightToolBarArea,
			"4": QtCore.Qt.TopToolBarArea,
			"8": QtCore.Qt.BottomToolBarArea
		}
		
		self.app = app
		self.setObjectName("JAJADIY")	# 持久化所必须的
		self.setWindowTitle("JAJADIY")	# 工具栏标题
		
		# 读取配置文件中的toolbar位置，如果没有，则放在窗口左侧
		if not app.ini.value("toolbar/area"):
			app.mainWindow.addToolBar(QtCore.Qt.LeftToolBarArea, self)
		else:
			app.mainWindow.addToolBar(self.toolbarArea[str(app.ini.value("toolbar/area"))], self)
		
		# 批量渲染窗口
		self.batchRenderWindow = None
		# 找回丢失资源窗口
		self.findMissingAssetWindow = None
		
		# 一键导入CAD Action
		importCADIcon = QtGui.QIcon(app.rootPath + "/icon/import_cad.png")
		importCADAction = QtWidgets.QAction(importCADIcon, "粘贴CAD", app.mainWindow)
		importCADAction.triggered.connect(self.importCAD)
		self.addAction(importCADAction)
		
		# 坐标一键归零
		axisZeroIcon = QtGui.QIcon(app.rootPath + "/icon/axis_zero.png")
		axisZeroAction = QtWidgets.QAction(axisZeroIcon, "一键归零", app.mainWindow)
		axisZeroAction.triggered.connect(self.zeroingAxis)
		self.addAction(axisZeroAction)
		
		# 复制模型
		self.addAction(CopyModelAction.CopyModelAction(app))
		# 粘贴模型
		self.addAction(PasteModelAction.PasteModelAction(app))
		# 建模工具
		self.buildModelAction = BuildModel.BuildModelAction(app)
		self.addAction(self.buildModelAction)
		
		
		# 查找丢失资源
		findMissingAssetIcon = QtGui.QIcon(app.rootPath + "/icon/find_missing_assets.png")
		self.findMissingAssetAction = QtWidgets.QAction(findMissingAssetIcon, "查找丢失资源", app.mainWindow)
		self.findMissingAssetAction.triggered.connect(self.showFMAWindow)
		self.findMissingAssetAction.setCheckable(True)
		self.addAction(self.findMissingAssetAction)
		
		self.addSeparator()
		
		# 九宫格
		ninePlaceGridIcon = QtGui.QIcon(app.rootPath + "/icon/nine_place_grid.png")
		ninePlaceGridAction = QtWidgets.QAction(ninePlaceGridIcon, "九宫格\n当开启安全框时生效", app.mainWindow)
		ninePlaceGridAction.setCheckable(True)
		ninePlaceGridAction.triggered.connect(app.ninePlaceGrid.toggle)
		self.addAction(ninePlaceGridAction)
		
		# 选中当前相机
		cameraSelectIcon = QtGui.QIcon(app.rootPath + "/icon/camera_select.png")
		cameraSelectAction = QtWidgets.QAction(cameraSelectIcon, "选中当前相机\n仅在相机视图生效", app.mainWindow)
		cameraSelectAction.triggered.connect(app.cameraUtil.selectCurrentCamera)
		self.addAction(cameraSelectAction)
		
		# 记录相机
		cameraMarkIcon = QtGui.QIcon(app.rootPath + "/icon/camera_mark.png")
		cameraMarkAction = QtWidgets.QAction(cameraMarkIcon, "记录相机尺寸\n仅在相机视图生效", app.mainWindow)
		cameraMarkAction.triggered.connect(app.cameraUtil.markCurrentCamera)
		self.addAction(cameraMarkAction)
		
		# 一键渲染
		self.renderAction = render.RenderAction(app)
		self.addAction(self.renderAction)
		
		self.addSeparator()
		
		# 关于JAJADIY
		self.addAction(About.AboutAction(app))
		
		# 注册保存场景成功后的通知
		rt.callbacks.removeScripts(rt.name("filePostSave"), id=rt.name("saveToolbarState"))
		rt.execute("fn saveToolbarState = ()")
		rt.saveToolbarState = self.saveToolbarState
		rt.callbacks.addScript(rt.name("filePostSave"), "saveToolbarState()", id=rt.name("saveToolbarState"))
		
	# 保存工具栏状态
	def saveToolbarState(self):
		self.app.ini.setValue("toolbar/area", self.app.mainWindow.toolBarArea(self))
		self.app.ini.sync()
	
	# 一键导入CAD
	@QtCore.Slot()
	def importCAD(self):
		tempDir = os.getenv("Temp")
		fileList = os.listdir(tempDir)
		dwg = None
		for f in fileList:
			if(f.lower().endswith(".dwg")):
				dwg = f
				break
		if dwg:
			# 导入CAD
			with pymxs.undo(True, "粘贴CAD"):
				self.importDWGs = []
				# 添加sceneNodeAdded监听器
				rt.execute("fn onSceneNodeAdded = ()")
				rt.onSceneNodeAdded = self.onSceneNodeAdded
				rt.callbacks.addScript(rt.name("sceneNodeAdded"), "onSceneNodeAdded()", id=rt.name("onImportDWG"))
				rt.importFile(tempDir + "/" + dwg, rt.readValue(rt.StringStream("#noPrompt")))
				rt.callbacks.removeScripts(id=rt.name("onImportDWG"))
				
				colorBlack = rt.color(0, 0, 0)
				for o in self.importDWGs:
					o.material = None
					o.wirecolor = colorBlack
					o.name = rt.uniqueName("jajadiy_paste_dwg_")
				group = rt.group(self.importDWGs, name=rt.uniqueName("jajadiy_group_"))
				group.pos = rt.point3(0, 0, 0)

		else:
			# 未复制CAD
			# QtWidgets.QMessageBox.information(self.app.mainWindow, "提示", "请先到AutoCAD中复制你要粘贴的内容！")
			box = QtWidgets.QMessageBox(self.app.mainWindow)
			box.setWindowTitle("提示")
			box.setWindowIcon(self.app.logo)
			box.setIcon(QtWidgets.QMessageBox.Information)
			box.setText('\n请先到AutoCAD中复制你要粘贴的内容！')
			box.exec_()
	
	# 导入CAD时，开启sceneNodeAdded监听者
	# 该方法处理每当新物体被添加到场景时，将新添加的物体保存到列表中
	def onSceneNodeAdded(self):
		self.importDWGs.append(rt.callbacks.notificationParam())
			
	# 一键归0
	@QtCore.Slot()
	def zeroingAxis(self):
		with pymxs.undo(True, "一键归零"):
			for o in rt.selection:
				# 判断是否是组或是否是非组物体
				if rt.isGroupHead(o) or not rt.isGroupMember(o):
					o.pos = rt.point3(0, 0, 0)
		rt.redrawViews()
	
	# 显示找回丢失资源对话框
	@QtCore.Slot()
	def showFMAWindow(self):
		if self.findMissingAssetAction.isChecked():
			if not self.findMissingAssetWindow:
				self.findMissingAssetWindow = FindMissingAssetWindow(self.app)
			self.findMissingAssetWindow.show()
		else:
			self.findMissingAssetWindow.close()
		
		
# 查找丢失资源窗口
class FindMissingAssetWindow(QtWidgets.QMainWindow):
	def __init__(self, app):
		super(FindMissingAssetWindow, self).__init__(app.mainWindow)
		self.app = app
		self.setWindowTitle("查找丢失资源")
		self.setWindowIcon(app.logo)
		
		vbox = QtWidgets.QVBoxLayout()
		vbox.setSpacing(8)
		vbox.setMargin(8)
		
		# 检查丢失资源按钮
		checkButton = QtWidgets.QPushButton("检查丢失资源")
		checkButton.clicked.connect(self.checkMissingAsset)
		vbox.addWidget(checkButton)
		
		# 相机列表
		self.assetList = QtWidgets.QListWidget()
		vbox.addWidget(self.assetList)
		
		# 一键找回
		findButton = QtWidgets.QPushButton("一键找回")
		findButton.clicked.connect(self.findAsset)
		vbox.addWidget(findButton)
		
		center = QtWidgets.QWidget()
		center.setLayout(vbox)
		self.setCentralWidget(center)
		
		# 设置窗口尺寸
		self.width = 250
		self.height = 300
		self.setMaximumSize(self.width, self.height)
		self.setMinimumSize(self.width, self.height)
		
	# 监听关闭事件
	def closeEvent(self, event):
		self.app.toolbar.findMissingAssetAction.setChecked(False)
		
	# 添加列表项
	def addListItem(self, name):
		lst = os.path.split(name)
		item = QtWidgets.QListWidgetItem(lst[1])
		self.assetList.addItem(item)
		
	# 删除列表项
	def removeListItem(self, name):
		lst = os.path.split(name)
		selectedItem = None
		for i in range(self.assetList.count()):
			item = self.assetList.item(i)
			if item.text() == lst[1]:
				selectedItem = item
				break
		self.assetList.takeItem(self.assetList.row(selectedItem))
	
	# 清空列表
	def clearList(self):
		while self.assetList.count():
			self.assetList.takeItem(0)
		
	# 检查丢失资源
	@QtCore.Slot()
	def checkMissingAsset(self):
		rt.ATSOps.Visible = True
		self.clearList()
		rt.execute('''
			diyMissingFiles = #()
			ATSOps.GetFilesByFileSystemStatus #Missing &diyMissingFiles
		''')
		for f in rt.diyMissingFiles:
			self.addListItem(f)
		rt.ATSOps.Visible = False
			
	#一键找回资源
	@QtCore.Slot()
	def findAsset(self):
		selectedDir = rt.getSavePath(caption="选择资源所在路径")
		# 当点击取消时，会返回None，因此做如下判断
		if selectedDir:
			# 遍历丢失资源列表
			for f in rt.diyMissingFiles:
				# 一个一个来，莫慌，所以要把之前选中取消选中
				rt.ATSOps.ClearSelection()
				# 生成临时列表变量，供maxscript在选中丢失文件时调用
				rt.execute(u"diyTempFile = #(1)")
				rt.execute(u'diyTempFile[1] = "{}"'.format(f))
				# 选中单个丢失文件
				rt.execute(u"ATSOps.SelectFiles &diyTempFile")
				# 注意：pythone和maxscript的下标起始位置不同
				newPath = self.findFile(selectedDir, rt.diyTempFile[0])
				if newPath:
					rt.ATSOps.SetPathOnSelection(newPath)
					# 从列表中移除已找到的资源
					self.removeListItem(f)
			rt.redrawViews()
				
	# 从指定目录中寻找文件
	# return 找到则返回找到的目录，没找到则返回 None
	def findFile(self, sPath, sFile):
		# 指定的文件是包含目录的，在这里只需要文件名
		fileName = (os.path.split(sFile))[1]
		for curDir, dirs, files in os.walk(sPath):
			for f in files:
				if f == fileName:
					return curDir